// ==UserScript==
// @name         北向云推送系统导出推送记录
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  导出推送记录为Excel
// @author       jialesmile
// @match        https://north.bowaniot.com/manage/menu-statistics/wkWUpktbAGkj0SYP?appName=aLink
// @updateURL    https://gitee.com/tangjiale/tampermonkey/raw/master/bowaniot/north_bowaniot_export_record.js
// @downloadURL  https://gitee.com/tangjiale/tampermonkey/raw/master/bowaniot/north_bowaniot_export_record.js
// @grant        GM_xmlhttpRequest
// @grant        GM_download
// ==/UserScript==

(function() {
    'use strict';

    // 添加导出按钮
    function addExportButton() {
        const searchButton = document.querySelector('.n-button--primary-type');
        if (searchButton) {
            const exportButton = document.createElement('button');
            exportButton.innerText = '导出';

            // 设置样式
            exportButton.style.backgroundColor = 'red'; // 背景颜色为红色
            exportButton.style.color = 'white'; // 字体颜色为白色
            exportButton.style.border = 'none'; // 去掉边框
            exportButton.style.cursor = 'pointer'; // 鼠标悬停时显示为指针
            exportButton.style.fontWeight = '400'; // 字体粗细
            exportButton.style.fontSize = '14px'; // 字体大小
            exportButton.style.padding = '0 14px'; // 内边距
            exportButton.style.borderRadius = '6px'; // 边角圆润
            exportButton.style.height = '34px'; // 高度
            exportButton.style.marginLeft = '10px'; // 左边距
            exportButton.onclick = exportData;

            // 插入导出按钮
            searchButton.parentNode.insertBefore(exportButton, searchButton.nextSibling);
        } else {
            // 如果没有找到搜索按钮，继续检查
            setTimeout(addExportButton, 100); // 每100毫秒检查一次
        }
    }

    // 显示遮罩层
function showLoadingOverlay() {
    const overlay = document.createElement('div');
    overlay.id = 'loading-overlay';
    overlay.style.position = 'fixed';
    overlay.style.top = '0';
    overlay.style.left = '0';
    overlay.style.width = '100%';
    overlay.style.height = '100%';
    overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
    overlay.style.color = 'white';
    overlay.style.display = 'flex';
    overlay.style.alignItems = 'center';
    overlay.style.justifyContent = 'center';
    overlay.style.fontSize = '20px';
    overlay.innerText = '导出中...';
    overlay.style.zIndex = '9999'; // 设置 z-index 确保在最上层
    document.body.appendChild(overlay);
    return overlay;
}

    // 隐藏遮罩层
    function hideLoadingOverlay() {
        const overlay = document.getElementById('loading-overlay');
        if (overlay) {
            document.body.removeChild(overlay);
        }
    }

    // 导出数据的功能
    async function exportData() {
        const token = getLocalStorageItem('SOY_token');
        const dateValue = getDateValue(); // 获取输入框的值


        // 显示遮罩层并获取其引用
        const overlay = showLoadingOverlay();

        const totalPages = await getTotalPage(token, dateValue);
        const allData = [];

        for (let start = 1; start <= totalPages; start += 1) {
            const data = await fetchData(token, start, dateValue);
            if (Array.isArray(data)) { // 检查 data 是否为数组
                allData.push(...data);
            } else {
                console.warn("获取的数据不是数组:", data);
            }

            const currentNum =start * 99;
            const currentTotalNum = totalPages* 99
            // 更新遮罩层文本
            overlay.innerText = `导出中,导出进度：已导出 ${currentNum}/${currentTotalNum} 条`;
            // 等待 0.5 秒
            await new Promise(resolve => setTimeout(resolve, 500));
        }

        // 导出为Excel
        downloadExcel(allData);

        // 隐藏遮罩层
        hideLoadingOverlay();
    }

    function getLocalStorageItem(key) {
        const value = localStorage.getItem(key).replaceAll('\"','');
        if (value) {
            console.log(`获取到的本地存储值: ${value}`); // 调试信息
            return value;
        }
        console.warn(`未找到本地存储项: ${key}`); // 警告信息
        return null; // 返回null以表示未找到
    }

    function getDateValue() {
        const dateInputs = document.querySelectorAll('.n-input__input-el[placeholder="选择日期"]');
        if (dateInputs.length > 0) {
            return dateInputs[0].value.trim(); // 获取第一个输入框的值并去除空格
        }
        return '';
    }

    function getTotalPage(token, dateValue) {
        return new Promise((resolve) => {
        const url = `https://north.bowaniot.com/smkgw/inorthmanageservice/api/v1.0.0/northreport/query/app/push/record?appId=wkWUpktbAGkj0SYP${dateValue ? `&day=${dateValue}` : ''}&start=1&limit=99`;

        GM_xmlhttpRequest({
            method: "GET",
            url: url,
            headers: {
                "Authorization": `Basic ${token}`
            },
            onload: function(response) {
                console.log("响应状态:", response.status); // 输出状态码
                console.log("响应文本:", response.responseText); // 输出响应文本


                    try {
                        const data = JSON.parse(response.responseText);
                        const total = data.data.total
                         // 计算总页数，使用 Math.ceil 进行进一法处理
                        const totalPages = Math.ceil(total / 99);
                        resolve(totalPages);
                    } catch (error) {
                        console.error("解析响应时出错:", error);
                        resolve(0); // 返回0以避免无限循环
                    }

            },
            onerror: function(error) {
                console.error("请求出错:", error);
                resolve(0); // 返回0以避免无限循环
            }
        });
    });
}

    function fetchData(token, start, dateValue,retries = 3 ) {
        return new Promise((resolve) => {
            const url = `https://north.bowaniot.com/smkgw/inorthmanageservice/api/v1.0.0/northreport/query/app/push/record?appId=wkWUpktbAGkj0SYP${dateValue ? `&day=${dateValue}` : ''}&start=${start}&limit=99`;
            GM_xmlhttpRequest({
                method: "GET",
                url: url,
                headers: {
                    "Authorization": `Basic ${token}`
                },
                onload: function(response) {
                console.log("响应状态:", response.status); // 输出状态码
                //console.log("响应文本:", response.responseText); // 输出响应文本

                if (response.status === 200) {
                    try {
                        const data = JSON.parse(response.responseText);
                        resolve(data.data.list);
                    } catch (error) {
                        console.error("解析响应时出错:", error);

                        resolve([]); // 返回空数组以避免错误
                    }
                } else if (response.status === 504 && retries > 0) {
                    console.warn("请求超时，正在重试...");
                    setTimeout(() => {
                        getTotalRecords(token, dateValue, retries - 1).then(resolve);
                    }, 3000); // 等待2秒后重试
                } else {
                    console.error("请求失败，状态码:", response.status);
                    resolve([]); // 返回空数组以避免错误
                }
            },
            onerror: function(error) {
                console.error("请求出错:", error);
                alert(error);
                resolve([]); // 返回空数组以避免错误
            }
            });
        });
    }

    function downloadExcel(data) {
    if (data.length === 0) {
        console.warn("没有数据可导出");
        alert("没有数据可导出")
        return;
    }

    // 获取字段名称作为标题
    const headers = Object.keys(data[0]).join(","); // 获取第一个对象的键作为标题
    const csvContent = "data:text/csv;charset=utf-8,"
        + headers + "\n" // 添加标题行
        + data.map(e => Object.values(e).join(",")).join("\n"); // 添加数据行

    const encodedUri = encodeURI(csvContent);
    const link = document.createElement("a");
    link.setAttribute("href", encodedUri);
    link.setAttribute("download", "push_records.csv");
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
}

    // 启动脚本，添加导出按钮
    addExportButton();
})();